<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>class OpenSSL::SSL::SSLContext - openssl: Ruby Standard Library Documentation</title>


<script src="../../js/navigation.js" defer></script>
<script src="../../js/search.js" defer></script>
<script src="../../js/search_index.js" defer></script>
<script src="../../js/searcher.js" defer></script>
<script src="../../js/darkfish.js" defer></script>

<script src="../../js/jquery-3.2.0.min.js"></script>

<script src="../../js/vue.min.js"></script>
<script src="../../js/js.cookie.min.js"></script>

<link href="../../css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="../../css/rdoc.css" rel="stylesheet">
<link href="../../css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "../../";
  var index_rel_prefix = "../../";
  var darkModeCsseHref = "../../css/rdoc-dm.css"
  var defaultModeCssHref = "../../css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="class">
  <!-- this is class.html -->

  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0.preview2 NOT FOUND -->
  </div> <!-- end action bar -->

  <div class='wrapper hdiv'>

    


    <nav id='vapp' role="navigation">
    <div id="project-navigation">
      <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="../../index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="../../table_of_contents.html#pages">Pages</a>
    <a href="../../table_of_contents.html#classes">Classes</a>
    <a href="../../table_of_contents.html#methods">Methods</a>
  </div>
</div>

      <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

    </div>


    

    <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>
    <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
      <div id="class-metadata">
        
        
<div id="parent-class-section" class="nav-section">
  <h3>Parent</h3>

  <p class="link">Object
</div>

        
        
        
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
  <h3>Methods</h3>

  <ul class="link-list" role="directory">
    <li ><a href="#method-c-new">::new</a>
    <li ><a href="#method-i-add_certificate">#add_certificate</a>
    <li ><a href="#method-i-ciphers">#ciphers</a>
    <li ><a href="#method-i-ciphers-3D">#ciphers=</a>
    <li ><a href="#method-i-ciphersuites-3D">#ciphersuites=</a>
    <li ><a href="#method-i-ecdh_curves-3D">#ecdh_curves=</a>
    <li ><a href="#method-i-enable_fallback_scsv">#enable_fallback_scsv</a>
    <li ><a href="#method-i-flush_sessions">#flush_sessions</a>
    <li ><a href="#method-i-freeze">#freeze</a>
    <li ><a href="#method-i-max_version-3D">#max_version=</a>
    <li ><a href="#method-i-min_version-3D">#min_version=</a>
    <li ><a href="#method-i-options">#options</a>
    <li ><a href="#method-i-options-3D">#options=</a>
    <li ><a href="#method-i-security_level">#security_level</a>
    <li ><a href="#method-i-security_level-3D">#security_level=</a>
    <li ><a href="#method-i-session_add">#session_add</a>
    <li ><a href="#method-i-session_cache_mode">#session_cache_mode</a>
    <li ><a href="#method-i-session_cache_mode-3D">#session_cache_mode=</a>
    <li ><a href="#method-i-session_cache_size">#session_cache_size</a>
    <li ><a href="#method-i-session_cache_size-3D">#session_cache_size=</a>
    <li ><a href="#method-i-session_cache_stats">#session_cache_stats</a>
    <li ><a href="#method-i-session_remove">#session_remove</a>
    <li ><a href="#method-i-set_minmax_proto_version">#set_minmax_proto_version</a>
    <li ><a href="#method-i-set_params">#set_params</a>
    <li ><a href="#method-i-setup">#setup</a>
    <li ><a href="#method-i-ssl_version-3D">#ssl_version=</a>
    <li ><a href="#method-i-tmp_dh-3D">#tmp_dh=</a>
  </ul>
</div>

      </div>
     </div>
    </nav>


    <div id='extraz'><div class='adzbox-index'  >
      
     </div>         
    </div>

    <main role="main" aria-labelledby="class-OpenSSL::SSL::SSLContext">
    <h1 id="class-OpenSSL::SSL::SSLContext" class="class">
      class OpenSSL::SSL::SSLContext
    </h1>

    <section class="description">
    
<p>An <a href="SSLContext.html"><code>SSLContext</code></a> is used to set various options regarding certificates, algorithms, verification, session caching, etc.  The <a href="SSLContext.html"><code>SSLContext</code></a> is used to create an <a href="SSLSocket.html"><code>SSLSocket</code></a>.</p>

<p>All attributes must be set before creating an <a href="SSLSocket.html"><code>SSLSocket</code></a> as the <a href="SSLContext.html"><code>SSLContext</code></a> will be frozen afterward.</p>

    </section>

      <section id="5Buntitled-5D" class="documentation-section">


      <section class="constants-list">
      <header>
      <h3>Constants</h3>
      </header>
      <dl>
          <dt id="DH_ffdhe2048">DH_ffdhe2048
          <dd>
          <dt id="METHODS">METHODS
          <dd><p>The list of available SSL/TLS methods. This constant is only provided for backwards compatibility.</p>
          <dt id="METHODS_MAP">METHODS_MAP
          <dd>
          <dt id="SESSION_CACHE_BOTH">SESSION_CACHE_BOTH
          <dd><p>Both client and server sessions are added to the session cache</p>
          <dt id="SESSION_CACHE_CLIENT">SESSION_CACHE_CLIENT
          <dd><p>Client sessions are added to the session cache</p>
          <dt id="SESSION_CACHE_NO_AUTO_CLEAR">SESSION_CACHE_NO_AUTO_CLEAR
          <dd><p>Normally the session cache is checked for expired sessions every 255 connections.  Since this may lead to a delay that cannot be controlled, the automatic flushing may be disabled and <a href="SSLContext.html#method-i-flush_sessions"><code>flush_sessions</code></a> can be called explicitly.</p>
          <dt id="SESSION_CACHE_NO_INTERNAL">SESSION_CACHE_NO_INTERNAL
          <dd><p>Enables both <a href="SSLContext.html#SESSION_CACHE_NO_INTERNAL_LOOKUP"><code>SESSION_CACHE_NO_INTERNAL_LOOKUP</code></a> and <a href="SSLContext.html#SESSION_CACHE_NO_INTERNAL_STORE"><code>SESSION_CACHE_NO_INTERNAL_STORE</code></a>.</p>
          <dt id="SESSION_CACHE_NO_INTERNAL_LOOKUP">SESSION_CACHE_NO_INTERNAL_LOOKUP
          <dd><p>Always perform external lookups of sessions even if they are in the internal cache.</p>

<p>This flag has no effect on clients</p>
          <dt id="SESSION_CACHE_NO_INTERNAL_STORE">SESSION_CACHE_NO_INTERNAL_STORE
          <dd><p>Never automatically store sessions in the internal store.</p>
          <dt id="SESSION_CACHE_OFF">SESSION_CACHE_OFF
          <dd><p>No session caching for client or server</p>
          <dt id="SESSION_CACHE_SERVER">SESSION_CACHE_SERVER
          <dd><p>Server sessions are added to the session cache</p>
        </dl>
        </section>

        <section class="attribute-method-details" class="method-section">
        <header>
        <h3>Attributes</h3>
        </header>

          <div id="attribute-i-alpn_protocols" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">alpn_protocols</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>An Enumerable of Strings. Each String represents a protocol to be advertised as the list of supported protocols for Application-Layer Protocol Negotiation. Supported in <a href="../../OpenSSL.html"><code>OpenSSL</code></a> 1.0.2 and higher. Has no effect on the server side. If not set explicitly, the ALPN extension will not be included in the handshake.</p>

<h3 id="attribute-i-alpn_protocols-label-Example">Example<span><a href="#attribute-i-alpn_protocols-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">alpn_protocols</span> = [<span class="ruby-string">&quot;http/1.1&quot;</span>, <span class="ruby-string">&quot;spdy/2&quot;</span>, <span class="ruby-string">&quot;h2&quot;</span>]
</pre>
              </div>
            </div>
          <div id="attribute-i-alpn_select_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">alpn_select_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked on the server side when the server needs to select a protocol from the list sent by the client. Supported in <a href="../../OpenSSL.html"><code>OpenSSL</code></a> 1.0.2 and higher. The callback must return a protocol of those advertised by the client. If none is acceptable, raising an error in the callback will cause the handshake to fail. Not setting this callback explicitly means not supporting the ALPN extension on the server - any protocols advertised by the client will be ignored.</p>

<h3 id="attribute-i-alpn_select_cb-label-Example">Example<span><a href="#attribute-i-alpn_select_cb-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">alpn_select_cb</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">protocols</span><span class="ruby-operator">|</span>
  <span class="ruby-comment"># inspect the protocols and select one</span>
  <span class="ruby-identifier">protocols</span>.<span class="ruby-identifier">first</span>
<span class="ruby-keyword">end</span>
</pre>
              </div>
            </div>
          <div id="attribute-i-ca_file" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">ca_file</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>The path to a file containing a PEM-format CA certificate</p>
              </div>
            </div>
          <div id="attribute-i-ca_path" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">ca_path</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>The path to a directory containing CA certificates in PEM format.</p>

<p>Files are looked up by subject’s <a href="../X509.html"><code>X509</code></a> name’s hash value.</p>
              </div>
            </div>
          <div id="attribute-i-cert" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">cert</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Context certificate</p>

<p>The <em>cert</em>, <em>key</em>, and <em>extra_chain_cert</em> attributes are deprecated. It is recommended to use <a href="SSLContext.html#method-i-add_certificate"><code>add_certificate</code></a> instead.</p>
              </div>
            </div>
          <div id="attribute-i-cert_store" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">cert_store</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>An <a href="../X509/Store.html"><code>OpenSSL::X509::Store</code></a> used for certificate verification.</p>
              </div>
            </div>
          <div id="attribute-i-client_ca" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">client_ca</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A certificate or Array of certificates that will be sent to the client.</p>
              </div>
            </div>
          <div id="attribute-i-client_cert_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">client_cert_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked when a client certificate is requested by a server and no certificate has been set.</p>

<p>The callback is invoked with a <a href="Session.html"><code>Session</code></a> and must return an Array containing an <a href="../X509/Certificate.html"><code>OpenSSL::X509::Certificate</code></a> and an <a href="../PKey.html"><code>OpenSSL::PKey</code></a>.  If any other value is returned the handshake is suspended.</p>
              </div>
            </div>
          <div id="attribute-i-extra_chain_cert" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">extra_chain_cert</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>An Array of extra <a href="../X509.html"><code>X509</code></a> certificates to be added to the certificate chain.</p>

<p>The <em>cert</em>, <em>key</em>, and <em>extra_chain_cert</em> attributes are deprecated. It is recommended to use <a href="SSLContext.html#method-i-add_certificate"><code>add_certificate</code></a> instead.</p>
              </div>
            </div>
          <div id="attribute-i-key" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">key</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Context private key</p>

<p>The <em>cert</em>, <em>key</em>, and <em>extra_chain_cert</em> attributes are deprecated. It is recommended to use <a href="SSLContext.html#method-i-add_certificate"><code>add_certificate</code></a> instead.</p>
              </div>
            </div>
          <div id="attribute-i-keylog_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">keylog_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked when TLS key material is generated or received, in order to allow applications to store this keying material for debugging purposes.</p>

<p>The callback is invoked with an <a href="SSLSocket.html"><code>SSLSocket</code></a> and a string containing the key material in the format used by NSS for its SSLKEYLOGFILE debugging output.</p>

<p>It is only compatible with <a href="../../OpenSSL.html"><code>OpenSSL</code></a> &gt;= 1.1.1. Even if LibreSSL implements SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see <a href="https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6">github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6</a>).</p>

<h3 id="attribute-i-keylog_cb-label-Example">Example<span><a href="#attribute-i-keylog_cb-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">context</span>.<span class="ruby-identifier">keylog_cb</span> = <span class="ruby-identifier">proc</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">_sock</span>, <span class="ruby-identifier">line</span><span class="ruby-operator">|</span>
  <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;ssl_keylog_file&#39;</span>, <span class="ruby-string">&quot;a&quot;</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">f</span>.<span class="ruby-identifier">write</span>(<span class="ruby-node">&quot;#{line}\n&quot;</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>
              </div>
            </div>
          <div id="attribute-i-npn_protocols" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">npn_protocols</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>An Enumerable of Strings. Each String represents a protocol to be advertised as the list of supported protocols for Next Protocol Negotiation. Supported in <a href="../../OpenSSL.html"><code>OpenSSL</code></a> 1.0.1 and higher. Has no effect on the client side. If not set explicitly, the NPN extension will not be sent by the server in the handshake.</p>

<h3 id="attribute-i-npn_protocols-label-Example">Example<span><a href="#attribute-i-npn_protocols-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">npn_protocols</span> = [<span class="ruby-string">&quot;http/1.1&quot;</span>, <span class="ruby-string">&quot;spdy/2&quot;</span>]
</pre>
              </div>
            </div>
          <div id="attribute-i-npn_select_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">npn_select_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked on the client side when the client needs to select a protocol from the list sent by the server. Supported in <a href="../../OpenSSL.html"><code>OpenSSL</code></a> 1.0.1 and higher. The client MUST select a protocol of those advertised by the server. If none is acceptable, raising an error in the callback will cause the handshake to fail. Not setting this callback explicitly means not supporting the NPN extension on the client - any protocols advertised by the server will be ignored.</p>

<h3 id="attribute-i-npn_select_cb-label-Example">Example<span><a href="#attribute-i-npn_select_cb-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">npn_select_cb</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">protocols</span><span class="ruby-operator">|</span>
  <span class="ruby-comment"># inspect the protocols and select one</span>
  <span class="ruby-identifier">protocols</span>.<span class="ruby-identifier">first</span>
<span class="ruby-keyword">end</span>
</pre>
              </div>
            </div>
          <div id="attribute-i-renegotiation_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">renegotiation_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked whenever a new handshake is initiated on an established connection. May be used to disable renegotiation entirely.</p>

<p>The callback is invoked with the active <a href="SSLSocket.html"><code>SSLSocket</code></a>. The callback’s return value is ignored. A normal return indicates “approval” of the renegotiation and will continue the process. To forbid renegotiation and to cancel the process, raise an exception within the callback.</p>

<h3 id="attribute-i-renegotiation_cb-label-Disable+client+renegotiation">Disable client renegotiation<span><a href="#attribute-i-renegotiation_cb-label-Disable+client+renegotiation">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>When running a server, it is often desirable to disable client renegotiation entirely. You may use a callback as follows to implement this feature:</p>

<pre class="ruby"><span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">renegotiation_cb</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ssl</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">raise</span> <span class="ruby-constant">RuntimeError</span>, <span class="ruby-string">&quot;Client renegotiation disabled&quot;</span>
<span class="ruby-keyword">end</span>
</pre>
              </div>
            </div>
          <div id="attribute-i-servername_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">servername_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked at connect time to distinguish between multiple server names.</p>

<p>The callback is invoked with an <a href="SSLSocket.html"><code>SSLSocket</code></a> and a server name.  The callback must return an <a href="SSLContext.html"><code>SSLContext</code></a> for the server name or nil.</p>
              </div>
            </div>
          <div id="attribute-i-session_get_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">session_get_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked on a server when a session is proposed by the client but the session could not be found in the server’s internal cache.</p>

<p>The callback is invoked with the <a href="SSLSocket.html"><code>SSLSocket</code></a> and session id.  The callback may return a <a href="Session.html"><code>Session</code></a> from an external cache.</p>
              </div>
            </div>
          <div id="attribute-i-session_id_context" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">session_id_context</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Sets the context in which a session can be reused.  This allows sessions for multiple applications to be distinguished, for example, by name.</p>
              </div>
            </div>
          <div id="attribute-i-session_new_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">session_new_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked when a new session was negotiated.</p>

<p>The callback is invoked with an <a href="SSLSocket.html"><code>SSLSocket</code></a>.  If <code>false</code> is returned the session will be removed from the internal cache.</p>
              </div>
            </div>
          <div id="attribute-i-session_remove_cb" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">session_remove_cb</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked when a session is removed from the internal cache.</p>

<p>The callback is invoked with an <a href="SSLContext.html"><code>SSLContext</code></a> and a <a href="Session.html"><code>Session</code></a>.</p>

<p>IMPORTANT NOTE: It is currently not possible to use this safely in a multi-threaded application. The callback is called inside a global lock and it can randomly cause deadlock on Ruby thread switching.</p>
              </div>
            </div>
          <div id="attribute-i-ssl_timeout" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">ssl_timeout</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Maximum session lifetime in seconds.</p>
              </div>
            </div>
          <div id="attribute-i-timeout" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">timeout</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Maximum session lifetime in seconds.</p>
              </div>
            </div>
          <div id="attribute-i-tmp_dh_callback" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">tmp_dh_callback</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback invoked when DH parameters are required for ephemeral DH key exchange.</p>

<p>The callback is invoked with the <a href="SSLSocket.html"><code>SSLSocket</code></a>, a flag indicating the use of an export cipher and the keylength required.</p>

<p>The callback must return an <a href="../PKey/DH.html"><code>OpenSSL::PKey::DH</code></a> instance of the correct key length.</p>

<p><strong>Deprecated in version 3.0.</strong> Use <a href="SSLContext.html#method-i-tmp_dh-3D"><code>tmp_dh=</code></a> instead.</p>
              </div>
            </div>
          <div id="attribute-i-verify_callback" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">verify_callback</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>A callback for additional certificate verification.  The callback is invoked for each certificate in the chain.</p>

<p>The callback is invoked with two values.  <em>preverify_ok</em> indicates indicates if the verification was passed (<code>true</code>) or not (<code>false</code>). <em>store_context</em> is an <a href="../X509/StoreContext.html"><code>OpenSSL::X509::StoreContext</code></a> containing the context used for certificate verification.</p>

<p>If the callback returns <code>false</code>, the chain verification is immediately stopped and a bad_certificate alert is then sent.</p>
              </div>
            </div>
          <div id="attribute-i-verify_depth" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">verify_depth</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Number of CA certificates to walk when verifying a certificate chain.</p>
              </div>
            </div>
          <div id="attribute-i-verify_hostname" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">verify_hostname</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p>Whether to check the server certificate is valid for the hostname.</p>

<p>In order to make this work, <a href="SSLContext.html#attribute-i-verify_mode"><code>verify_mode</code></a> must be set to VERIFY_PEER and the server hostname must be given by <a href="SSLSocket.html#method-i-hostname-3D"><code>OpenSSL::SSL::SSLSocket#hostname=</code></a>.</p>
              </div>
            </div>
          <div id="attribute-i-verify_mode" class="method-detail">
            <div class="method-heading attribute-method-heading">
              <span class="method-name">verify_mode</span><span
                class="attribute-access-type">[RW]</span>
            </div>

            <div class="method-description">
              <p><a href="Session.html"><code>Session</code></a> verification mode.</p>

<p>Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT and defined on <a href="../SSL.html"><code>OpenSSL::SSL</code></a></p>

<p>The default mode is VERIFY_NONE, which does not perform any verification at all.</p>

<p>See SSL_CTX_set_verify(3) for details.</p>
              </div>
            </div>
            </section>


                <section id="public-class-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Class Methods</h3>
                </header>

                  <div id="method-c-new" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          new           &rarr; ctx
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          new(:TLSv1)   &rarr; ctx
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          new(&quot;SSLv23&quot;) &rarr; ctx
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Creates a new <a href="../SSL.html"><code>SSL</code></a> context.</p>

<p>If an argument is given, <a href="SSLContext.html#method-i-ssl_version-3D"><code>ssl_version=</code></a> is called with the value. Note that this form is deprecated. New applications should use <a href="SSLContext.html#method-i-min_version-3D"><code>min_version=</code></a> and <a href="SSLContext.html#method-i-max_version-3D"><code>max_version=</code></a> as necessary.</p>

                              <div class="method-source-code" id="new-source">
            <pre><span class="ruby-comment"># File openssl/lib/openssl/ssl.rb, line 127</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">initialize</span>(<span class="ruby-identifier">version</span> = <span class="ruby-keyword">nil</span>)
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">options</span> <span class="ruby-operator">|=</span> <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">OP_ALL</span>
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ssl_version</span> = <span class="ruby-identifier">version</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">version</span>
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">verify_mode</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">VERIFY_NONE</span>
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">verify_hostname</span> = <span class="ruby-keyword">false</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                          </section>

                <section id="public-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Instance Methods</h3>
                </header>

                  <div id="method-i-add_certificate" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          add_certificate(certificate, pkey [, extra_certs]) &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Adds a certificate to the context. <em>pkey</em> must be a corresponding private key with <em>certificate</em>.</p>

<p>Multiple certificates with different public key type can be added by repeated calls of this method, and <a href="../../OpenSSL.html"><code>OpenSSL</code></a> will choose the most appropriate certificate during the handshake.</p>

<p><a href="SSLContext.html#attribute-i-cert"><code>cert=</code></a>, <a href="SSLContext.html#attribute-i-key"><code>key=</code></a>, and <a href="SSLContext.html#attribute-i-extra_chain_cert"><code>extra_chain_cert=</code></a> are old accessor methods for setting certificate and internally call this method.</p>

<h3 id="method-i-add_certificate-label-Parameters">Parameters<span><a href="#method-i-add_certificate-label-Parameters">&para;</a> <a href="#top">&uarr;</a></span></h3>
<dl class="rdoc-list note-list"><dt><em>certificate</em>
<dd>
<p>A certificate. An instance of <a href="../X509/Certificate.html"><code>OpenSSL::X509::Certificate</code></a>.</p>
</dd><dt><em>pkey</em>
<dd>
<p>The private key for <em>certificate</em>. An instance of <a href="../PKey/PKey.html"><code>OpenSSL::PKey::PKey</code></a>.</p>
</dd><dt><em>extra_certs</em>
<dd>
<p>Optional. An array of <a href="../X509/Certificate.html"><code>OpenSSL::X509::Certificate</code></a>. When sending a certificate chain, the certificates specified by this are sent following <em>certificate</em>, in the order in the array.</p>
</dd></dl>

<h3 id="method-i-add_certificate-label-Example">Example<span><a href="#method-i-add_certificate-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre>rsa_cert = OpenSSL::X509::Certificate.new(...)
rsa_pkey = OpenSSL::PKey.read(...)
ca_intermediate_cert = OpenSSL::X509::Certificate.new(...)
ctx.add_certificate(rsa_cert, rsa_pkey, [ca_intermediate_cert])

ecdsa_cert = ...
ecdsa_pkey = ...
another_ca_cert = ...
ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])</pre>

                              <div class="method-source-code" id="add_certificate-source">
            <pre>static VALUE
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
{
    VALUE cert, key, extra_chain_ary;
    SSL_CTX *ctx;
    X509 *x509;
    STACK_OF(X509) *extra_chain = NULL;
    EVP_PKEY *pkey, *pub_pkey;

    GetSSLCTX(self, ctx);
    rb_scan_args(argc, argv, &quot;21&quot;, &amp;cert, &amp;key, &amp;extra_chain_ary);
    rb_check_frozen(self);
    x509 = GetX509CertPtr(cert);
    pkey = GetPrivPKeyPtr(key);

    /*
     * The reference counter is bumped, and decremented immediately.
     * X509_get0_pubkey() is only available in OpenSSL &gt;= 1.1.0.
     */
    pub_pkey = X509_get_pubkey(x509);
    EVP_PKEY_free(pub_pkey);
    if (!pub_pkey)
        rb_raise(rb_eArgError, &quot;certificate does not contain public key&quot;);
    if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
        rb_raise(rb_eArgError, &quot;public key mismatch&quot;);

    if (argc &gt;= 3)
        extra_chain = ossl_x509_ary2sk(extra_chain_ary);

    if (!SSL_CTX_use_certificate(ctx, x509)) {
        sk_X509_pop_free(extra_chain, X509_free);
        ossl_raise(eSSLError, &quot;SSL_CTX_use_certificate&quot;);
    }
    if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
        sk_X509_pop_free(extra_chain, X509_free);
        ossl_raise(eSSLError, &quot;SSL_CTX_use_PrivateKey&quot;);
    }
    if (extra_chain &amp;&amp; !SSL_CTX_set0_chain(ctx, extra_chain)) {
        sk_X509_pop_free(extra_chain, X509_free);
        ossl_raise(eSSLError, &quot;SSL_CTX_set0_chain&quot;);
    }
    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-ciphers" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphers &rarr; [[name, version, bits, alg_bits], ...]
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>The list of cipher suites configured for this context.</p>

                              <div class="method-source-code" id="ciphers-source">
            <pre>static VALUE
ossl_sslctx_get_ciphers(VALUE self)
{
    SSL_CTX *ctx;
    STACK_OF(SSL_CIPHER) *ciphers;
    const SSL_CIPHER *cipher;
    VALUE ary;
    int i, num;

    GetSSLCTX(self, ctx);
    ciphers = SSL_CTX_get_ciphers(ctx);
    if (!ciphers)
        return rb_ary_new();

    num = sk_SSL_CIPHER_num(ciphers);
    ary = rb_ary_new2(num);
    for(i = 0; i &lt; num; i++){
        cipher = sk_SSL_CIPHER_value(ciphers, i);
        rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
    }
    return ary;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-ciphers-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphers = &quot;cipher1:cipher2:...&quot;
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphers = [name, ...]
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphers = [[name, version, bits, alg_bits], ...]
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Sets the list of available cipher suites for this context.  Note in a server context some ciphers require the appropriate certificates.  For example, an RSA cipher suite can only be chosen when an RSA certificate is available.</p>

                              <div class="method-source-code" id="ciphers-3D-source">
            <pre>static VALUE
ossl_sslctx_set_ciphers(VALUE self, VALUE v)
{
    SSL_CTX *ctx;
    VALUE str;

    rb_check_frozen(self);
    if (NIL_P(v))
        return v;

    str = build_cipher_string(v);

    GetSSLCTX(self, ctx);
    if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
        ossl_raise(eSSLError, &quot;SSL_CTX_set_cipher_list&quot;);

    return v;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-ciphersuites-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphersuites = &quot;cipher1:cipher2:...&quot;
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphersuites = [name, ...]
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          ciphersuites = [[name, version, bits, alg_bits], ...]
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Sets the list of available TLSv1.3 cipher suites for this context.</p>

                              <div class="method-source-code" id="ciphersuites-3D-source">
            <pre>static VALUE
ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
{
    SSL_CTX *ctx;
    VALUE str;

    rb_check_frozen(self);
    if (NIL_P(v))
        return v;

    str = build_cipher_string(v);

    GetSSLCTX(self, ctx);
    if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str)))
        ossl_raise(eSSLError, &quot;SSL_CTX_set_ciphersuites&quot;);

    return v;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-ecdh_curves-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          ecdh_curves = curve_list &rarr; curve_list
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the list of “supported elliptic curves” for this context.</p>

<p>For a TLS client, the list is directly used in the Supported Elliptic Curves Extension. For a server, the list is used by <a href="../../OpenSSL.html"><code>OpenSSL</code></a> to determine the set of shared curves. <a href="../../OpenSSL.html"><code>OpenSSL</code></a> will pick the most appropriate one from it.</p>

<h3 id="method-i-ecdh_curves-3D-label-Example">Example<span><a href="#method-i-ecdh_curves-3D-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">ctx1</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLContext</span>.<span class="ruby-identifier">new</span>
<span class="ruby-identifier">ctx1</span>.<span class="ruby-identifier">ecdh_curves</span> = <span class="ruby-string">&quot;X25519:P-256:P-224&quot;</span>
<span class="ruby-identifier">svr</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLServer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">tcp_svr</span>, <span class="ruby-identifier">ctx1</span>)
<span class="ruby-constant">Thread</span>.<span class="ruby-identifier">new</span> { <span class="ruby-identifier">svr</span>.<span class="ruby-identifier">accept</span> }

<span class="ruby-identifier">ctx2</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLContext</span>.<span class="ruby-identifier">new</span>
<span class="ruby-identifier">ctx2</span>.<span class="ruby-identifier">ecdh_curves</span> = <span class="ruby-string">&quot;P-256&quot;</span>
<span class="ruby-identifier">cli</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLSocket</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">tcp_sock</span>, <span class="ruby-identifier">ctx2</span>)
<span class="ruby-identifier">cli</span>.<span class="ruby-identifier">connect</span>

<span class="ruby-identifier">p</span> <span class="ruby-identifier">cli</span>.<span class="ruby-identifier">tmp_key</span>.<span class="ruby-identifier">group</span>.<span class="ruby-identifier">curve_name</span>
<span class="ruby-comment"># =&gt; &quot;prime256v1&quot; (is an alias for NIST P-256)</span>
</pre>

                              <div class="method-source-code" id="ecdh_curves-3D-source">
            <pre>static VALUE
ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;

    rb_check_frozen(self);
    GetSSLCTX(self, ctx);
    StringValueCStr(arg);

    if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
        ossl_raise(eSSLError, NULL);
    return arg;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-enable_fallback_scsv" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          enable_fallback_scsv() &rarr; nil
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Activate TLS_FALLBACK_SCSV for this context. See RFC 7507.</p>

                              <div class="method-source-code" id="enable_fallback_scsv-source">
            <pre>static VALUE
ossl_sslctx_enable_fallback_scsv(VALUE self)
{
    SSL_CTX *ctx;

    GetSSLCTX(self, ctx);
    SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);

    return Qnil;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-flush_sessions" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          flush_sessions(time) &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Removes sessions in the internal cache that have expired at <em>time</em>.</p>

                              <div class="method-source-code" id="flush_sessions-source">
            <pre>static VALUE
ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
{
    VALUE arg1;
    SSL_CTX *ctx;
    time_t tm = 0;

    rb_scan_args(argc, argv, &quot;01&quot;, &amp;arg1);

    GetSSLCTX(self, ctx);

    if (NIL_P(arg1)) {
        tm = time(0);
    } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
        tm = NUM2LONG(rb_funcall(arg1, rb_intern(&quot;to_i&quot;), 0));
    } else {
        ossl_raise(rb_eArgError, &quot;arg must be Time or nil&quot;);
    }

    SSL_CTX_flush_sessions(ctx, (long)tm);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-freeze" class="method-detail method-alias">
                            <div class="method-heading">
                              <span class="method-name">freeze</span><span
                                class="method-args">()</span>
                            </div>

                            <div class="method-description">
                              <p>This method is called automatically when a new <a href="SSLSocket.html"><code>SSLSocket</code></a> is created. However, it is not thread-safe and must be called before creating <a href="SSLSocket.html"><code>SSLSocket</code></a> objects in a multi-threaded program.</p>

                            </div>


                            <div class="aliases">
                              Alias for: <a href="SSLContext.html#method-i-setup">setup</a>
                            </div>
                          </div>

                  <div id="method-i-max_version-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          max_version = OpenSSL::SSL::TLS1_2_VERSION
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          max_version = :TLS1_2
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          max_version = nil
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Sets the upper bound of the supported SSL/TLS protocol version. See <a href="SSLContext.html#method-i-min_version-3D"><code>min_version=</code></a> for the possible values.</p>

                              <div class="method-source-code" id="max_version-3D-source">
            <pre><span class="ruby-comment"># File openssl/lib/openssl/ssl.rb, line 190</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">max_version=</span>(<span class="ruby-identifier">version</span>)
  <span class="ruby-identifier">set_minmax_proto_version</span>(<span class="ruby-ivar">@min_proto_version</span> <span class="ruby-operator">||=</span> <span class="ruby-keyword">nil</span>, <span class="ruby-identifier">version</span>)
  <span class="ruby-ivar">@max_proto_version</span> = <span class="ruby-identifier">version</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-min_version-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          min_version = OpenSSL::SSL::TLS1_2_VERSION
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          min_version = :TLS1_2
                              </span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          min_version = nil
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Sets the lower bound on the supported SSL/TLS protocol version. The version may be specified by an integer constant named OpenSSL::SSL::*_VERSION, a Symbol, or <code>nil</code> which means “any version”.</p>

<p>Be careful that you don’t overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v* options by <a href="SSLContext.html#method-i-options-3D"><code>options=</code></a> once you have called <a href="SSLContext.html#method-i-min_version-3D"><code>min_version=</code></a> or <a href="SSLContext.html#method-i-max_version-3D"><code>max_version=</code></a>.</p>

<h3 id="method-i-min_version-3D-label-Example">Example<span><a href="#method-i-min_version-3D-label-Example">&para;</a> <a href="#top">&uarr;</a></span></h3>

<pre class="ruby"><span class="ruby-identifier">ctx</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLContext</span>.<span class="ruby-identifier">new</span>
<span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">min_version</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">TLS1_1_VERSION</span>
<span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">max_version</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">TLS1_2_VERSION</span>

<span class="ruby-identifier">sock</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLSocket</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">tcp_sock</span>, <span class="ruby-identifier">ctx</span>)
<span class="ruby-identifier">sock</span>.<span class="ruby-identifier">connect</span> <span class="ruby-comment"># Initiates a connection using either TLS 1.1 or TLS 1.2</span>
</pre>

                              <div class="method-source-code" id="min_version-3D-source">
            <pre><span class="ruby-comment"># File openssl/lib/openssl/ssl.rb, line 178</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">min_version=</span>(<span class="ruby-identifier">version</span>)
  <span class="ruby-identifier">set_minmax_proto_version</span>(<span class="ruby-identifier">version</span>, <span class="ruby-ivar">@max_proto_version</span> <span class="ruby-operator">||=</span> <span class="ruby-keyword">nil</span>)
  <span class="ruby-ivar">@min_proto_version</span> = <span class="ruby-identifier">version</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-options" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">options</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Gets various <a href="../../OpenSSL.html"><code>OpenSSL</code></a> options.</p>

                              <div class="method-source-code" id="options-source">
            <pre>static VALUE
ossl_sslctx_get_options(VALUE self)
{
    SSL_CTX *ctx;
    GetSSLCTX(self, ctx);
    /*
     * Do explicit cast because SSL_CTX_get_options() returned (signed) long in
     * OpenSSL before 1.1.0.
     */
    return ULONG2NUM((unsigned long)SSL_CTX_get_options(ctx));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-options-3D" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">options=</span><span
                                class="method-args">(p1)</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets various <a href="../../OpenSSL.html"><code>OpenSSL</code></a> options.</p>

                              <div class="method-source-code" id="options-3D-source">
            <pre>static VALUE
ossl_sslctx_set_options(VALUE self, VALUE options)
{
    SSL_CTX *ctx;

    rb_check_frozen(self);
    GetSSLCTX(self, ctx);

    SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));

    if (NIL_P(options)) {
        SSL_CTX_set_options(ctx, SSL_OP_ALL);
    } else {
        SSL_CTX_set_options(ctx, NUM2ULONG(options));
    }

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-security_level" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          security_level &rarr; Integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the security level for the context.</p>

<p>See also <a href="SSLContext.html#method-i-security_level-3D"><code>OpenSSL::SSL::SSLContext#security_level=</code></a>.</p>

                              <div class="method-source-code" id="security_level-source">
            <pre>static VALUE
ossl_sslctx_get_security_level(VALUE self)
{
    SSL_CTX *ctx;

    GetSSLCTX(self, ctx);

#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
    return INT2NUM(SSL_CTX_get_security_level(ctx));
#else
    (void)ctx;
    return INT2FIX(0);
#endif
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-security_level-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          security_level = integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the security level for the context. <a href="../../OpenSSL.html"><code>OpenSSL</code></a> limits parameters according to the level. The “parameters” include: ciphersuites, curves, key sizes, certificate signature algorithms, protocol version and so on. For example, level 1 rejects parameters offering below 80 bits of security, such as ciphersuites using MD5 for the MAC or RSA keys shorter than 1024 bits.</p>

<p>Note that attempts to set such parameters with insufficient security are also blocked. You need to lower the level first.</p>

<p>This feature is not supported in <a href="../../OpenSSL.html"><code>OpenSSL</code></a> &lt; 1.1.0, and setting the level to other than 0 will raise NotImplementedError. Level 0 means everything is permitted, the same behavior as previous versions of <a href="../../OpenSSL.html"><code>OpenSSL</code></a>.</p>

<p>See the manpage of SSL_CTX_set_security_level(3) for details.</p>

                              <div class="method-source-code" id="security_level-3D-source">
            <pre>static VALUE
ossl_sslctx_set_security_level(VALUE self, VALUE value)
{
    SSL_CTX *ctx;

    rb_check_frozen(self);
    GetSSLCTX(self, ctx);

#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
    SSL_CTX_set_security_level(ctx, NUM2INT(value));
#else
    (void)ctx;
    if (NUM2INT(value) != 0)
        ossl_raise(rb_eNotImpError, &quot;setting security level to other than 0 is &quot;
                   &quot;not supported in this version of OpenSSL&quot;);
#endif

    return value;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_add" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_add(session) &rarr; true | false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Adds <em>session</em> to the session cache.</p>

                              <div class="method-source-code" id="session_add-source">
            <pre>static VALUE
ossl_sslctx_session_add(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;

    GetSSLCTX(self, ctx);
    GetSSLSession(arg, sess);

    return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_cache_mode" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_cache_mode &rarr; Integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>The current session cache mode.</p>

                              <div class="method-source-code" id="session_cache_mode-source">
            <pre>static VALUE
ossl_sslctx_get_session_cache_mode(VALUE self)
{
    SSL_CTX *ctx;

    GetSSLCTX(self, ctx);

    return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_cache_mode-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_cache_mode=(integer) &rarr; Integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the <a href="../SSL.html"><code>SSL</code></a> session cache mode.  Bitwise-or together the desired SESSION_CACHE_* constants to set.  See SSL_CTX_set_session_cache_mode(3) for details.</p>

                              <div class="method-source-code" id="session_cache_mode-3D-source">
            <pre>static VALUE
ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;

    GetSSLCTX(self, ctx);

    SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));

    return arg;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_cache_size" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_cache_size &rarr; Integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the current session cache size.  Zero is used to represent an unlimited cache size.</p>

                              <div class="method-source-code" id="session_cache_size-source">
            <pre>static VALUE
ossl_sslctx_get_session_cache_size(VALUE self)
{
    SSL_CTX *ctx;

    GetSSLCTX(self, ctx);

    return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_cache_size-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_cache_size=(integer) &rarr; Integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the session cache size.  Returns the previously valid session cache size.  Zero is used to represent an unlimited session cache size.</p>

                              <div class="method-source-code" id="session_cache_size-3D-source">
            <pre>static VALUE
ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;

    GetSSLCTX(self, ctx);

    SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));

    return arg;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_cache_stats" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_cache_stats &rarr; Hash
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns a Hash containing the following keys:</p>
<dl class="rdoc-list note-list"><dt>:accept
<dd>
<p>Number of started SSL/TLS handshakes in server mode</p>
</dd><dt>:accept_good
<dd>
<p>Number of established SSL/TLS sessions in server mode</p>
</dd><dt>:accept_renegotiate
<dd>
<p>Number of start renegotiations in server mode</p>
</dd><dt>:cache_full
<dd>
<p>Number of sessions that were removed due to cache overflow</p>
</dd><dt>:cache_hits
<dd>
<p>Number of successfully reused connections</p>
</dd><dt>:cache_misses
<dd>
<p>Number of sessions proposed by clients that were not found in the cache</p>
</dd><dt>:cache_num
<dd>
<p>Number of sessions in the internal session cache</p>
</dd><dt>:cb_hits
<dd>
<p>Number of sessions retrieved from the external cache in server mode</p>
</dd><dt>:connect
<dd>
<p>Number of started SSL/TLS handshakes in client mode</p>
</dd><dt>:connect_good
<dd>
<p>Number of established SSL/TLS sessions in client mode</p>
</dd><dt>:connect_renegotiate
<dd>
<p>Number of start renegotiations in client mode</p>
</dd><dt>:timeouts
<dd>
<p>Number of sessions proposed by clients that were found in the cache but had expired due to timeouts</p>
</dd></dl>

                              <div class="method-source-code" id="session_cache_stats-source">
            <pre>static VALUE
ossl_sslctx_get_session_cache_stats(VALUE self)
{
    SSL_CTX *ctx;
    VALUE hash;

    GetSSLCTX(self, ctx);

    hash = rb_hash_new();
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;cache_num&quot;)), LONG2NUM(SSL_CTX_sess_number(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;connect&quot;)), LONG2NUM(SSL_CTX_sess_connect(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;connect_good&quot;)), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;connect_renegotiate&quot;)), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;accept&quot;)), LONG2NUM(SSL_CTX_sess_accept(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;accept_good&quot;)), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;accept_renegotiate&quot;)), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;cache_hits&quot;)), LONG2NUM(SSL_CTX_sess_hits(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;cb_hits&quot;)), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;cache_misses&quot;)), LONG2NUM(SSL_CTX_sess_misses(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;cache_full&quot;)), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));
    rb_hash_aset(hash, ID2SYM(rb_intern(&quot;timeouts&quot;)), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));

    return hash;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-session_remove" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          session_remove(session) &rarr; true | false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Removes <em>session</em> from the session cache.</p>

                              <div class="method-source-code" id="session_remove-source">
            <pre>static VALUE
ossl_sslctx_session_remove(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    SSL_SESSION *sess;

    GetSSLCTX(self, ctx);
    GetSSLSession(arg, sess);

    return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-set_params" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          set_params(params = {}) &rarr; params
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets saner defaults optimized for the use with HTTP-like protocols.</p>

<p>If a Hash <em>params</em> is given, the parameters are overridden with it. The keys in <em>params</em> must be assignment methods on <a href="SSLContext.html"><code>SSLContext</code></a>.</p>

<p>If the <a href="SSLContext.html#attribute-i-verify_mode"><code>verify_mode</code></a> is not VERIFY_NONE and <a href="SSLContext.html#attribute-i-ca_file"><code>ca_file</code></a>, <a href="SSLContext.html#attribute-i-ca_path"><code>ca_path</code></a> and <a href="SSLContext.html#attribute-i-cert_store"><code>cert_store</code></a> are not set then the system default certificate store is used.</p>

                              <div class="method-source-code" id="set_params-source">
            <pre><span class="ruby-comment"># File openssl/lib/openssl/ssl.rb, line 146</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">set_params</span>(<span class="ruby-identifier">params</span>={})
  <span class="ruby-identifier">params</span> = <span class="ruby-constant">DEFAULT_PARAMS</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-identifier">params</span>)
  <span class="ruby-keyword">self</span>.<span class="ruby-identifier">options</span> = <span class="ruby-identifier">params</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-value">:options</span>) <span class="ruby-comment"># set before min_version/max_version</span>
  <span class="ruby-identifier">params</span>.<span class="ruby-identifier">each</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">name</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">__send__</span>(<span class="ruby-node">&quot;#{name}=&quot;</span>, <span class="ruby-identifier">value</span>) }
  <span class="ruby-keyword">if</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">verify_mode</span> <span class="ruby-operator">!=</span> <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">VERIFY_NONE</span>
    <span class="ruby-keyword">unless</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ca_file</span> <span class="ruby-keyword">or</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">ca_path</span> <span class="ruby-keyword">or</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">cert_store</span>
      <span class="ruby-keyword">self</span>.<span class="ruby-identifier">cert_store</span> = <span class="ruby-constant">DEFAULT_CERT_STORE</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">return</span> <span class="ruby-identifier">params</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-setup" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          setup &rarr; Qtrue # first time
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          setup &rarr; nil # thereafter
                              </span>
                            </div>

                            <div class="method-description">
                              <p>This method is called automatically when a new <a href="SSLSocket.html"><code>SSLSocket</code></a> is created. However, it is not thread-safe and must be called before creating <a href="SSLSocket.html"><code>SSLSocket</code></a> objects in a multi-threaded program.</p>

                              <div class="method-source-code" id="setup-source">
            <pre>static VALUE
ossl_sslctx_setup(VALUE self)
{
    SSL_CTX *ctx;
    X509 *cert = NULL, *client_ca = NULL;
    EVP_PKEY *key = NULL;
    char *ca_path = NULL, *ca_file = NULL;
    int verify_mode;
    long i;
    VALUE val;

    if(OBJ_FROZEN(self)) return Qnil;
    GetSSLCTX(self, ctx);

#if !defined(OPENSSL_NO_DH)
    SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
#endif

#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
    SSL_CTX_set_post_handshake_auth(ctx, 1);
#endif

    val = rb_attr_get(self, id_i_cert_store);
    if (!NIL_P(val)) {
        X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
        SSL_CTX_set_cert_store(ctx, store);
        X509_STORE_up_ref(store);
    }

    val = rb_attr_get(self, id_i_extra_chain_cert);
    if(!NIL_P(val)){
        rb_block_call(val, rb_intern(&quot;each&quot;), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
    }

    /* private key may be bundled in certificate file. */
    val = rb_attr_get(self, id_i_cert);
    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
    val = rb_attr_get(self, id_i_key);
    key = NIL_P(val) ? NULL : GetPrivPKeyPtr(val); /* NO DUP NEEDED */
    if (cert &amp;&amp; key) {
        if (!SSL_CTX_use_certificate(ctx, cert)) {
            /* Adds a ref =&gt; Safe to FREE */
            ossl_raise(eSSLError, &quot;SSL_CTX_use_certificate&quot;);
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            /* Adds a ref =&gt; Safe to FREE */
            ossl_raise(eSSLError, &quot;SSL_CTX_use_PrivateKey&quot;);
        }
        if (!SSL_CTX_check_private_key(ctx)) {
            ossl_raise(eSSLError, &quot;SSL_CTX_check_private_key&quot;);
        }
    }

    val = rb_attr_get(self, id_i_client_ca);
    if(!NIL_P(val)){
        if (RB_TYPE_P(val, T_ARRAY)) {
            for(i = 0; i &lt; RARRAY_LEN(val); i++){
                client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
                if (!SSL_CTX_add_client_CA(ctx, client_ca)){
                    /* Copies X509_NAME =&gt; FREE it. */
                    ossl_raise(eSSLError, &quot;SSL_CTX_add_client_CA&quot;);
                }
            }
        }
        else{
            client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
            if (!SSL_CTX_add_client_CA(ctx, client_ca)){
                /* Copies X509_NAME =&gt; FREE it. */
                ossl_raise(eSSLError, &quot;SSL_CTX_add_client_CA&quot;);
            }
        }
    }

    val = rb_attr_get(self, id_i_ca_file);
    ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
    val = rb_attr_get(self, id_i_ca_path);
    ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
#ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE
    if (ca_file &amp;&amp; !SSL_CTX_load_verify_file(ctx, ca_file))
        ossl_raise(eSSLError, &quot;SSL_CTX_load_verify_file&quot;);
    if (ca_path &amp;&amp; !SSL_CTX_load_verify_dir(ctx, ca_path))
        ossl_raise(eSSLError, &quot;SSL_CTX_load_verify_dir&quot;);
#else
    if (ca_file || ca_path) {
        if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
            ossl_raise(eSSLError, &quot;SSL_CTX_load_verify_locations&quot;);
    }
#endif

    val = rb_attr_get(self, id_i_verify_mode);
    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
    if (RTEST(rb_attr_get(self, id_i_client_cert_cb)))
        SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);

    val = rb_attr_get(self, id_i_timeout);
    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));

    val = rb_attr_get(self, id_i_verify_depth);
    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));

#ifdef OSSL_USE_NEXTPROTONEG
    val = rb_attr_get(self, id_i_npn_protocols);
    if (!NIL_P(val)) {
        VALUE encoded = ssl_encode_npn_protocols(val);
        rb_ivar_set(self, id_npn_protocols_encoded, encoded);
        SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
        OSSL_Debug(&quot;SSL NPN advertise callback added&quot;);
    }
    if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
        SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
        OSSL_Debug(&quot;SSL NPN select callback added&quot;);
    }
#endif

    val = rb_attr_get(self, id_i_alpn_protocols);
    if (!NIL_P(val)) {
        VALUE rprotos = ssl_encode_npn_protocols(val);

        /* returns 0 on success */
        if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos),
                                    RSTRING_LENINT(rprotos)))
            ossl_raise(eSSLError, &quot;SSL_CTX_set_alpn_protos&quot;);
        OSSL_Debug(&quot;SSL ALPN values added&quot;);
    }
    if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) {
        SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
        OSSL_Debug(&quot;SSL ALPN select callback added&quot;);
    }

    rb_obj_freeze(self);

    val = rb_attr_get(self, id_i_session_id_context);
    if (!NIL_P(val)){
        StringValue(val);
        if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
                                            RSTRING_LENINT(val))){
            ossl_raise(eSSLError, &quot;SSL_CTX_set_session_id_context&quot;);
        }
    }

    if (RTEST(rb_attr_get(self, id_i_session_get_cb))) {
        SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
        OSSL_Debug(&quot;SSL SESSION get callback added&quot;);
    }
    if (RTEST(rb_attr_get(self, id_i_session_new_cb))) {
        SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
        OSSL_Debug(&quot;SSL SESSION new callback added&quot;);
    }
    if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) {
        SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
        OSSL_Debug(&quot;SSL SESSION remove callback added&quot;);
    }

    val = rb_attr_get(self, id_i_servername_cb);
    if (!NIL_P(val)) {
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
        OSSL_Debug(&quot;SSL TLSEXT servername callback added&quot;);
    }

#if OPENSSL_VERSION_NUMBER &gt;= 0x10101000 &amp;&amp; !defined(LIBRESSL_VERSION_NUMBER)
    /*
     * It is only compatible with OpenSSL &gt;= 1.1.1. Even if LibreSSL implements
     * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
     * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
     */
    if (RTEST(rb_attr_get(self, id_i_keylog_cb))) {
        SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb);
        OSSL_Debug(&quot;SSL keylog callback added&quot;);
    }
#endif

    return Qtrue;
}</pre>
                              </div>
                            </div>

                            <div class="aliases">
                              Also aliased as: <a href="SSLContext.html#method-i-freeze">freeze</a>
                            </div>

                          </div>

                  <div id="method-i-ssl_version-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          ssl_version = :TLSv1
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          ssl_version = &quot;SSLv23&quot;
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Sets the SSL/TLS protocol version for the context. This forces connections to use only the specified protocol version. This is deprecated and only provided for backwards compatibility. Use <a href="SSLContext.html#method-i-min_version-3D"><code>min_version=</code></a> and <a href="SSLContext.html#method-i-max_version-3D"><code>max_version=</code></a> instead.</p>

<h3 id="method-i-ssl_version-3D-label-History">History<span><a href="#method-i-ssl_version-3D-label-History">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>As the name hints, this used to call the SSL_CTX_set_ssl_version() function which sets the <a href="../SSL.html"><code>SSL</code></a> method used for connections created from the context. As of Ruby/OpenSSL 2.1, this accessor method is implemented to call <a href="SSLContext.html#method-i-min_version-3D"><code>min_version=</code></a> and <a href="SSLContext.html#method-i-max_version-3D"><code>max_version=</code></a> instead.</p>

                              <div class="method-source-code" id="ssl_version-3D-source">
            <pre><span class="ruby-comment"># File openssl/lib/openssl/ssl.rb, line 209</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">ssl_version=</span>(<span class="ruby-identifier">meth</span>)
  <span class="ruby-identifier">meth</span> = <span class="ruby-identifier">meth</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">meth</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>)
  <span class="ruby-keyword">if</span> <span class="ruby-regexp">/(?&lt;type&gt;_client|_server)\z/</span> <span class="ruby-operator">=~</span> <span class="ruby-identifier">meth</span>
    <span class="ruby-identifier">meth</span> = <span class="ruby-node">$`</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">$VERBOSE</span>
      <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;#{caller(1, 1)[0]}: method type #{type.inspect} is ignored&quot;</span>
    <span class="ruby-keyword">end</span>
  <span class="ruby-keyword">end</span>
  <span class="ruby-identifier">version</span> = <span class="ruby-constant">METHODS_MAP</span>[<span class="ruby-identifier">meth</span>.<span class="ruby-identifier">intern</span>] <span class="ruby-keyword">or</span>
    <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-string">&quot;unknown SSL method `%s&#39;&quot;</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">meth</span>
  <span class="ruby-identifier">set_minmax_proto_version</span>(<span class="ruby-identifier">version</span>, <span class="ruby-identifier">version</span>)
  <span class="ruby-ivar">@min_proto_version</span> = <span class="ruby-ivar">@max_proto_version</span> = <span class="ruby-identifier">version</span>
<span class="ruby-keyword">end</span></pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-tmp_dh-3D" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          tmp_dh = pkey
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets DH parameters used for ephemeral DH key exchange. This is relevant for servers only.</p>

<p><code>pkey</code> is an instance of <a href="../PKey/DH.html"><code>OpenSSL::PKey::DH</code></a>. Note that key components contained in the key object, if any, are ignored. The server will always generate a new key pair for each handshake.</p>

<p>Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">ctx</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLContext</span>.<span class="ruby-identifier">new</span>
<span class="ruby-identifier">ctx</span>.<span class="ruby-identifier">tmp_dh</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">DH</span>.<span class="ruby-identifier">generate</span>(<span class="ruby-value">2048</span>)
<span class="ruby-identifier">svr</span> = <span class="ruby-constant">OpenSSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSL</span><span class="ruby-operator">::</span><span class="ruby-constant">SSLServer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">tcp_svr</span>, <span class="ruby-identifier">ctx</span>)
<span class="ruby-constant">Thread</span>.<span class="ruby-identifier">new</span> { <span class="ruby-identifier">svr</span>.<span class="ruby-identifier">accept</span> }
</pre>

                              <div class="method-source-code" id="tmp_dh-3D-source">
            <pre>static VALUE
ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
{
    SSL_CTX *ctx;
    EVP_PKEY *pkey;

    rb_check_frozen(self);
    GetSSLCTX(self, ctx);
    pkey = GetPKeyPtr(arg);

    if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
        rb_raise(eSSLError, &quot;invalid pkey type %s (expected DH)&quot;,
                 OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
#ifdef HAVE_SSL_SET0_TMP_DH_PKEY
    if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
        ossl_raise(eSSLError, &quot;SSL_CTX_set0_tmp_dh_pkey&quot;);
    EVP_PKEY_up_ref(pkey);
#else
    if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey)))
        ossl_raise(eSSLError, &quot;SSL_CTX_set_tmp_dh&quot;);
#endif

    return arg;
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

                <section id="private-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Private Instance Methods</h3>
                </header>

                  <div id="method-i-set_minmax_proto_version" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          set_minmax_proto_version(min, max) &rarr; nil
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Sets the minimum and maximum supported protocol versions. See <a href="SSLContext.html#method-i-min_version-3D"><code>min_version=</code></a> and <a href="SSLContext.html#method-i-max_version-3D"><code>max_version=</code></a>.</p>

                              <div class="method-source-code" id="set_minmax_proto_version-source">
            <pre>static VALUE
ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
{
    SSL_CTX *ctx;
    int min, max;

    GetSSLCTX(self, ctx);
    min = parse_proto_version(min_v);
    max = parse_proto_version(max_v);

#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
    if (!SSL_CTX_set_min_proto_version(ctx, min))
        ossl_raise(eSSLError, &quot;SSL_CTX_set_min_proto_version&quot;);
    if (!SSL_CTX_set_max_proto_version(ctx, max))
        ossl_raise(eSSLError, &quot;SSL_CTX_set_max_proto_version&quot;);
#else
    {
        unsigned long sum = 0, opts = 0;
        int i;
        static const struct {
            int ver;
            unsigned long opts;
        } options_map[] = {
            { SSL2_VERSION, SSL_OP_NO_SSLv2 },
            { SSL3_VERSION, SSL_OP_NO_SSLv3 },
            { TLS1_VERSION, SSL_OP_NO_TLSv1 },
            { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
            { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
# if defined(TLS1_3_VERSION)
            { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
# endif
        };

        for (i = 0; i &lt; numberof(options_map); i++) {
            sum |= options_map[i].opts;
            if ((min &amp;&amp; min &gt; options_map[i].ver) ||
                (max &amp;&amp; max &lt; options_map[i].ver)) {
                opts |= options_map[i].opts;
            }
        }
        SSL_CTX_clear_options(ctx, sum);
        SSL_CTX_set_options(ctx, opts);
    }
#endif

    return Qnil;
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

              </section>
              </main>



            </div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>.</p><p><a href="https://jamesbritt.bandcamp.com/">Maximum R+D</a>.  </p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

